
#include "../stdafx.h"
#include "CtlParaNode.h"
#include "math.h"


CCtlParaNode::CCtlParaNode()
{
	for(long i = 0; i < 200 ; i ++)
	{
		tmp_paras[i] = 0.0;
	}
}

CCtlParaNode::~CCtlParaNode()
{
	Empty();
}

CCtlParaNode & CCtlParaNode::operator= ( CCtlParaNode &obj)
{
	if(this == &obj)
	{
		return *this;
	}
	this->Empty();
	this->ctlpara_name = obj.ctlpara_name;

	long num = obj.paras.GetElementNum();
	for(long i = 0; i < num ; i ++)
	{
		CString name;
		obj.GetParaName(i,name);
		long vl;
		unsigned char vc;
		double vf;
		long type;
		obj.GetParaType(i,type);
		if(type==1)
		{
			obj.GetParaValue(i,vl);
			this->SetPara(name,vl);
		}
		if(type==2)
		{
			obj.GetParaValue(i,vc);
			this->SetPara(name,vc);
		}
		if(type==3)
		{
			obj.GetParaValue(i,vf);
			this->SetPara(name,vf);
		}
	}

	for( i = 0; i < 200 ; i ++)
	{
		this->tmp_paras[i] = obj.tmp_paras[i];
	}
	return * this;
}

bool CCtlParaNode::SaveParas(CString path)
{
	if(this->ctlpara_name.IsEmpty())
	{
		return false;
	}
	CFile fp;
	if(fp.Open(path,CFile::modeWrite|CFile::modeCreate)==false)
	{
		return false;
	}
	long ver = 1;
	CBaseFileOp::WriteInt(&fp,ver);
	CBaseFileOp::WriteString(&fp,this->ctlpara_name);
	ver = this->paras.GetElementNum();
	CBaseFileOp::WriteInt(&fp,ver);
	CtlParaCell * tmp;
	CtlParaCell_Int * tmpi;
	CtlParaCell_Char * tmpc;
	CtlParaCell_Float * tmpf;

	for(long i = 0; i < 200 ; i ++)
	{
		float td;
		td = this->tmp_paras[i];
		CBaseFileOp::WriteFloat32(&fp,td);
	}
	for( i = 0; i < ver ; i ++)
	{
		tmp = (CtlParaCell * )paras.GetElement(i);
		if(tmp->paratype == 1)
		{
			tmpi = (CtlParaCell_Int *)tmp;
			CBaseFileOp::WriteString(&fp,tmpi->paraname);
			CBaseFileOp::WriteInt(&fp,tmpi->paratype);
			CBaseFileOp::WriteInt(&fp,tmpi->v);
		}
		if(tmp->paratype == 2)
		{
			tmpc = (CtlParaCell_Char *)tmp;
			CBaseFileOp::WriteString(&fp,tmpc->paraname);
			CBaseFileOp::WriteInt(&fp,tmpc->paratype);
			CBaseFileOp::WriteChar(&fp,tmpc->v);
		}
		if(tmp->paratype == 3)
		{
			tmpf = (CtlParaCell_Float *)tmp;
			CBaseFileOp::WriteString(&fp,tmpf->paraname);
			CBaseFileOp::WriteInt(&fp,tmpf->paratype);
			CBaseFileOp::WriteFloat(&fp,tmpf->v);
		}
	}
	fp.Close();
	
	return true;
}


bool CCtlParaNode::IsValueEqual(CCtlParaNode &t)
{
	long num = this->paras.GetElementNum();
	if(num!=t.paras.GetElementNum())
	{
		return false;
	}
	long i;
	for( i = 0; i < num ; i ++)
	{
		CString name;
		this->GetParaName(i,name);
		long vl;
		unsigned char vc;
		double vf;
		long type;
		this->GetParaType(i,type);
		if(type==1)
		{
			this->GetParaValue(i,vl);
			if(t.CheckParaIn(name,vl)==false)
			{
				return false;
			}
		}
		if(type==2)
		{
			this->GetParaValue(i,vc);
			if(t.CheckParaIn(name,vc)==false)
			{
				return false;
			}
		}
		if(type==3)
		{
			this->GetParaValue(i,vf);
			if(t.CheckParaIn(name,vf)==false)
			{
				return false;
			}
		}
	}

	for( i = 0; i < num ; i ++)
	{
		CString name;
		t.GetParaName(i,name);
		long vl;
		unsigned char vc;
		double vf;
		long type;
		t.GetParaType(i,type);
		if(type==1)
		{
			t.GetParaValue(i,vl);
			if(this->CheckParaIn(name,vl)==false)
			{
				return false;
			}
		}
		if(type==2)
		{
			t.GetParaValue(i,vc);
			if(this->CheckParaIn(name,vc)==false)
			{
				return false;
			}
		}
		if(type==3)
		{
			t.GetParaValue(i,vf);
			if(this->CheckParaIn(name,vf)==false)
			{
				return false;
			}
		}
	}
	return true;
}
bool CCtlParaNode::IsNameEqual(CCtlParaNode &t)
{
	if(ctlpara_name.Compare(t.ctlpara_name) == 0)
	{
		return true;
	}
	return false;
}

bool CCtlParaNode::CheckParaIn(CString name,long v)
{
	if(name.IsEmpty())
	{
		return false;
	}
	CtlParaCell * tmp;
	long num = this->paras.GetElementNum();
	for(long i = 0; i < num ; i ++)
	{
		tmp = (CtlParaCell *)this->paras.GetElement(i);
		if(tmp->paraname.Compare(name)==0)
		{
			if(tmp->paratype == 1)
			{
				CtlParaCell_Int * tmp2 = (CtlParaCell_Int *)tmp;
				if(tmp2->v == v)
				{
					return true;
				}
			}
		}
	}
	return false;
}




bool CCtlParaNode::CheckParaIn(CString name,unsigned char v)
{
	if(name.IsEmpty())
	{
		return false;
	}
	CtlParaCell * tmp;
	long num = this->paras.GetElementNum();
	for(long i = 0; i < num ; i ++)
	{
		tmp = (CtlParaCell *)this->paras.GetElement(i);
		if(tmp->paraname.Compare(name)==0)
		{
			if(tmp->paratype == 2)
			{
				CtlParaCell_Char * tmp2 = (CtlParaCell_Char *)tmp;
				if(tmp2->v == v)
				{
					return true;
				}
			}
		}
	}
	return false;
}



bool CCtlParaNode::CheckParaIn(CString name,double v)
{
	if(name.IsEmpty())
	{
		return false;
	}
	CtlParaCell * tmp;
	long num = this->paras.GetElementNum();
	for(long i = 0; i < num ; i ++)
	{
		tmp = (CtlParaCell *)this->paras.GetElement(i);
		if(tmp->paraname.Compare(name)==0)
		{
			if(tmp->paratype == 3)
			{
				CtlParaCell_Float * tmp2 = (CtlParaCell_Float *)tmp;
				if(fabs(tmp2->v - v)<0.000000000001)
				{
					return true;
				}
			}
		}
	}
	return false;
}

bool CCtlParaNode::CheckNameIn(CString name)
{
	if(name.IsEmpty())
	{
		return true;
	}
	CtlParaCell * tmp;
	long num = this->paras.GetElementNum();
	for(long i = 0; i < num ; i ++)
	{
		tmp = (CtlParaCell *)this->paras.GetElement(i);
		if(tmp->paraname.Compare(name)==0)
		{
			return true;
		}
	}
	return false;
}



bool CCtlParaNode::LoadParas(CString path)
{
	CFile fp;
	if(fp.Open(path,CFile::modeRead)==false)
	{
		return false;
	}
	long ver;
	CBaseFileOp::ReadInt(&fp,ver);
	if(ver != 1)
	{
		fp.Close();
		return false;
	}
	this->Empty();
	CBaseFileOp::ReadString(&fp,this->ctlpara_name);
	CtlParaCell_Int * tmpi;
	CtlParaCell_Char * tmpc;
	CtlParaCell_Float * tmpf;

	CBaseFileOp::ReadInt(&fp,ver);

	CString s;
	long type;
	unsigned char vc;
	long	vi;
	double  vf;

	for(long i = 0; i < 200 ; i ++)
	{
		float td;
		CBaseFileOp::ReadFloat32(&fp,td);
		
		this->tmp_paras[i] = td;
	}

	for( i = 0; i < ver ; i ++)
	{

		if(CBaseFileOp::ReadString(&fp,s)==false)
		{
			fp.Close();
			Empty();
			return false;
		}

		if(CBaseFileOp::ReadInt(&fp,type)==false)
		{
			fp.Close();
			Empty();
			return false;
		}

		if(type == 1)
		{
			if(CBaseFileOp::ReadInt(&fp,vi)==false)
			{
				fp.Close();
				Empty();
				return false;
			}
			tmpi = new CtlParaCell_Int;
			tmpi->paraname = s;
			tmpi->paratype = type;
			tmpi->v = vi;
			paras.AddToChain(tmpi);
		}
		if(type == 2)
		{
			if(CBaseFileOp::ReadChar(&fp,vc)==false)
			{
				fp.Close();
				Empty();
				return false;
			}
			tmpc = new CtlParaCell_Char;
			tmpc->paraname = s;
			tmpc->paratype = type;
			tmpc->v = vc;
			paras.AddToChain(tmpc);
		}
		if(type == 3)
		{
			if(CBaseFileOp::ReadFloat(&fp,vf)==false)
			{
				fp.Close();
				Empty();
				return false;
			}
			tmpf = new CtlParaCell_Float;
			tmpf->paraname = s;
			tmpf->paratype = type;
			tmpf->v = vf;
			paras.AddToChain(tmpf);
		}
	}
	fp.Close();
	return true;
}

long CCtlParaNode::GetParaNum()
{
	return this->paras.GetElementNum();
}

bool CCtlParaNode::GetParaName(long serial,CString & ret_name)
{
	CtlParaCell * tmp;
	tmp = (CtlParaCell *)this->paras.GetElement(serial);
	if(tmp == NULL)
	{
		return false;
	}
	ret_name = tmp->paraname;
	return true;
}

bool CCtlParaNode::GetParaType(long serial,long & ret_type)
{
	CtlParaCell * tmp;
	tmp = (CtlParaCell *)this->paras.GetElement(serial);
	if(tmp == NULL)
	{
		return false;
	}
	ret_type = tmp->paratype;
	return true;
}



bool CCtlParaNode::SetPara(CString name,long v)
{
	if(name.IsEmpty())
	{
		return false;
	}
	long num   = this->GetParaNum();
	CString names;
	for(long i= 0; i < num ; i ++)
	{
		GetParaName(i,names);
		if(names.Compare(name)==0)
		{
			return false;
		}
		
	}
	CtlParaCell_Int * tmp;
	tmp = new CtlParaCell_Int ;
	tmp->paraname = name;
	tmp->paratype = 1;
	tmp->v = v;
	this->paras.AddToChain(tmp);
	return true;

}
bool CCtlParaNode::SetPara(CString name,unsigned char v)
{
	if(name.IsEmpty())
	{
		return false;
	}
	long num   = this->GetParaNum();
	CString names;
	for(long i= 0; i < num ; i ++)
	{
		GetParaName(i,names);
		if(names.Compare(name)==0)
		{
			return false;
		}
		
	}
	CtlParaCell_Char * tmp;
	tmp = new CtlParaCell_Char;
	tmp->paraname = name;
	tmp->paratype = 2;
	tmp->v = v;
	this->paras.AddToChain(tmp);
	return true;
}
bool CCtlParaNode::SetPara(CString name,double v)
{
	if(name.IsEmpty())
	{
		return false;
	}
	long num   = this->GetParaNum();
	CString names;
	for(long i= 0; i < num ; i ++)
	{
		GetParaName(i,names);
		if(names.Compare(name)==0)
		{
			return false;
		}
		
	}
	CtlParaCell_Float * tmp;
	tmp = new CtlParaCell_Float;
	tmp->paraname = name;
	tmp->paratype = 3;
	tmp->v = v;
	this->paras.AddToChain(tmp);
	return true;
}

bool CCtlParaNode::GetParaValue(long serial,long &vi)
{
	long type;
	if(GetParaType(serial,type)==false)
	{
		return false;
	}
	if(type != 1)
	{
		return false;
	}
	CtlParaCell_Int * tmp;
	tmp = (CtlParaCell_Int *)this->paras.GetElement(serial);
	if(tmp == NULL)
	{
		return false;
	}
	vi = tmp->v;
	return true;
}
bool CCtlParaNode::GetParaValue(long serial,unsigned char &vc)
{
	long type;
	if(GetParaType(serial,type)==false)
	{
		return false;
	}
	if(type != 2)
	{
		return false;
	}
	CtlParaCell_Char * tmp;
	tmp = (CtlParaCell_Char *)this->paras.GetElement(serial);
	if(tmp == NULL)
	{
		return false;
	}
	vc = tmp->v;
	return true;
}
bool CCtlParaNode::GetParaValue(long serial,double &vf)
{
	long type;
	if(GetParaType(serial,type)==false)
	{
		return false;
	}
	
	if(type != 3)
	{
		return false;
	}

	
	CtlParaCell_Float * tmp;
	tmp = (CtlParaCell_Float *)this->paras.GetElement(serial);
	if(tmp == NULL)
	{
		return false;
	}
	vf = tmp->v;
	return true;
}

void CCtlParaNode::Empty()
{
	CtlParaCell * tmp;
	long num = this->paras.GetElementNum();
	for(long i = 0; i < num ; i ++)
	{
		tmp = (CtlParaCell *)this->paras.GetElement(i);
		delete tmp;
	}
	this->paras.Empty();
	this->ctlpara_name.Empty();
}

bool CCtlParaNode::DeletPara(CString name)
{
	if(name.IsEmpty())
	{
		return false;
	}

	CtlParaCell * tmp;
	long num = this->paras.GetElementNum();
	for(long i = 0; i < num ; i ++)
	{
		tmp = (CtlParaCell *)this->paras.GetElement(i);
		if(tmp->paraname.Compare(name)==0)
		{
			this->paras.DeleteElement(i);
			delete (tmp);
			
			return true;
		}
	}
	return false;

}
